<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Coding 图床</title>
    <script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <script src="https://use.fontawesome.com/6364f396e2.js"></script>
    <script src="https://cdn.bootcss.com/clipboard.js/2.0.6/clipboard.min.js"></script>
    <link href="https://fonts.loli.net/css?family=Noto+Serif+SC|Noto+Sans+SC&display=swap" rel="stylesheet">
    <style>
        * {
            box-sizing: border-box;
            font-family: "Noto Sans SC", PingFang SC,Helvetica Neue,Hiragino Sans GB,Segoe UI,Microsoft YaHei,微软雅黑,sans-serif;
        }
        body { 
            margin: auto;
            max-width: 750px;
        }
        #app {
            display: flex;
            flex-direction: column;
            height: 100vh;
            padding: 0 20px;
        }
        .drag-area {
            flex: 1;
            background: #fff;
            text-align: center;
            cursor: pointer;
            border-radius: 10px;
            border: 1px dashed #555;
            overflow: hidden;
            position: relative;
            margin: 10px 0 10px;
            min-height: 200px;
            transition: border-color .2s ease;
        }

        
        .drag-area:hover {
            border: 1px dashed #2d8cf0;
            color: #2d8cf0;
        }

        .drag-area.drag-over, .drag-area:active {
            border: 2px dashed #2d8cf0;
            color: #2d8cf0;
        }

        .drag-title {
            position: absolute;
            top: 0;
            bottom: 0;
            font-size: 2em;
            width: 100%;
            left: 0;
            display: inline-block;
            margin: auto;
            height: 110px;
        }

        .drag-title i {
            font-size: 1.5em;
        }

        .img-list img {
            width: 100%;
        }

        .img-box {
            display: flex;
        }

        .img-view {
            flex: 1;
            vertical-align: middle;
            padding: 5px 0;
        }

        .img-urls {
            width: 80%;
            padding: 10px;
        }
        .img-urls input{
            width: 100%;
        }
        .img-urls p {
            margin: 0;
        }
        .img-urls h3 {
            margin: 10px 0;
        }
        .link {
            display: flex;
        }
        .copy-btn {
            border: 0;
            background-color: transparent;
            cursor: pointer;
        }
        .config {
            margin: 10px 0;
            font-size: 1.5em;
            /*display: flex;
            flex-direction: column;*/
            width: 100%;
            flex: 1;
        }
        .config .box {
            display: flex;
            flex-flow: row-reverse;

        }
        .config label {
            display: inline-block;
            width: 1.5em;
            text-align: center;
            line-height: 1.5;
        }
        .config input {
            flex: 1;
            border: 0;
            border-bottom: 1px dashed #555;
            font-size: .8em;
        }
        .config input:focus {
            outline: 0;
            border-bottom: 2px dashed #2d8cf0;

        }
        .config input:focus + label {
            color: #2d8cf0
        }
        .error {
            border: 1px solid #FF5722;
            background-color: #ffefe6;
            border-radius: 4px;
            color: #515a6e;
            padding: 8px 48px 8px 16px;
            margin: 10px 0;
        }
        .error i {
            color: #F44336;
        }
        .view {
            display:flex;
            height: 100%;
            flex-direction: column;
        }
        .header {
            text-align: center;
            /*display: flex;*/
        }
        .header .logo {
            font-family: "Noto Serif SC", PingFang SC,Helvetica Neue,Hiragino Sans GB,Segoe UI,Microsoft YaHei,微软雅黑,sans-serif;
            vertical-align: text-top;
        }
        .header .logo .fa {
            font-family: FontAwesome;
            font-size: 1.5em;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="header">
            <h1 class="logo"><i class="fa fa-picture-o logo icon" aria-hidden="true"></i> Coding 图床</h1>
        </div>
        <div class="config">
            <div class="box"><input type="text" id="token" v-model="config.token" placeholder="Coding 访问令牌"><label for="token" class="fa fa-ticket"></label></div>
            <div class="box"><input type="text" id="repo" v-model="config.repository" placeholder="Coding 仓库地址"><label for="repo" class="fa fa-code-fork"></label></div>
            <div class="box"><input type="text" id="dir" v-model="config.directoy" placeholder="保存到文件夹"><label for="dir" class="fa fa-folder"></label></div>
        </div>
        <div class="view">
            <div ref="drag-area" class="drag-area" :class="{'drag-over': isDrag}" @click="$refs['file'].click()">
                <span class="drag-title"><i class="fa fa-cloud-upload" aria-hidden="true"></i> <br/>拖拽到此或粘贴上传</span>
                <input type="file" ref="file" style="display: none;" @change="uploadHandle" accept="image/*" multiple>
            </div>
            <div class="error" v-if="error"><i class="fa fa-exclamation" aria-hidden="true"></i> 错误：{{error}}</div>
            <div class="img-list">
                <div v-for="i in images" class="img-box">
                    <div class="img-view"><img :src="i.blob" alt="" srcset=""></div>
                    <div class="img-urls">
                        <div v-if="i.urls">
                            <h3>外链地址</h3>
                            <p v-for="l in i.urls" class="link">
                                <input type="text" :value="l" onfocus="this.select()">
                                <button :data-clipboard-text="l" class="copy-btn fa-clipboard fa"></button>
                                <button :data-clipboard-text="'![](' + l + ')'" class="copy-btn">
                                    <svg style="width: 20px;" aria-hidden="true" focusable="false" data-prefix="fab" data-icon="markdown" class="svg-inline--fa fa-markdown fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M593.8 59.1H46.2C20.7 59.1 0 79.8 0 105.2v301.5c0 25.5 20.7 46.2 46.2 46.2h547.7c25.5 0 46.2-20.7 46.1-46.1V105.2c0-25.4-20.7-46.1-46.2-46.1zM338.5 360.6H277v-120l-61.5 76.9-61.5-76.9v120H92.3V151.4h61.5l61.5 76.9 61.5-76.9h61.5v209.2zm135.3 3.1L381.5 256H443V151.4h61.5V256H566z"></path></svg>
                                </button>
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <script>
            let vm = new Vue({
                el: '#app',
                data: {
                    images: [],
                    isDrag: false,
                    api: '/',
                    config: {
                        token: '',
                        repository: '',
                        directoy: '/'
                    },
                    error: ''
                },
                mounted() {
                    this.$refs['drag-area'].addEventListener('dragenter', this.dragenterHandler, false);
                    this.$refs['drag-area'].addEventListener('dragleave', this.dragleaveHandler, false);
                    this.$refs['drag-area'].addEventListener('dragover', this.dragoverHandler, false);
                    this.$refs['drag-area'].addEventListener('drop', this.dropHandler, false);
                    document.addEventListener('paste', this.pasteHandle, false);
                    new ClipboardJS('.copy-btn');
                    this.config.token = localStorage.getItem('token') || '';
                    this.config.repository = localStorage.getItem('repository') || '';
                },
                methods: {
                    upload(file, i) {
                        this.error = ''
                        let param = new FormData();

                        if (file.size > 1024 * 1024) {
                            this.images.splice(i, 1);
                            this.error = '文件太大了！请选择小于 1 MB 的图片';
                            return;
                        }
                        
                        if(this.config.token != '' && this.config.repository != '') {
                            param.append('t', this.config.token);
                            param.append('r', this.config.repository);
                        }
                        param.append('d', this.config.directoy);
                        param.append('f', file);
                        axios.post(this.api, param, {
                            headers: {
                                'Content-Type': 'multipart/form-data'
                            }
                        }).then(rsp => {
                            rsp = rsp.data;
                            if (rsp.status) {
                                this.error = rsp.msg;
                                this.images.splice(i, 1);
                                return;
                            }
                            this.images[i].urls = rsp.data.urls;
                            if(this.config.token != '' && this.config.repository != '') {
                                localStorage.setItem('token', this.config.token);
                                localStorage.setItem('repository', this.config.repository);
                            }
                        }).catch(err => {
                            this.error = err.message;
                            this.images.splice(i, 1);
                        })
                    },
                    previewFile(f) {
                        let reader = new FileReader();
                        reader.onload = (e) => {
                            this.upload(f, this.images.push({
                                blob: reader.result,
                                urls: null
                            }) - 1);
                        };
                        reader.readAsDataURL(f);
                    },
                    uploadHandle(e) {
                        let files = e.target.files;
                        Array.from(files).forEach(f => {
                            if (f.type.indexOf('image') < 0) return;
                            this.previewFile(f);
                        })
                    },
                    dragenterHandler(e) {
                        this.isDrag = true;
                        e.preventDefault();
                    },
                    dragleaveHandler(e) {
                        this.isDrag = false;
                    },
                    dragoverHandler(e) {
                        this.isDrag = true;
                        e.preventDefault();
                    },
                    dropHandler(e) {
                        this.isDrag = false;
                        let files = e.dataTransfer.files;
                        let i = 0;
                        Array.from(files).forEach(f => {
                            if (f.type.indexOf('image') < 0) return;
                            this.previewFile(f);
                        })
                        e.preventDefault();
                    },
                    pasteHandle(e) {
                        let items = event.clipboardData && event.clipboardData.items;
                        Array.from(items).forEach(f => {
                            if (f.type.indexOf('image') < 0) return;
                            let file = f.getAsFile();
                            this.previewFile(file);
                        })
                    }
                }
            })
        </script>
    </div>
    <div style="display: none;"><script type="text/javascript" src="https://s11.cnzz.com/z_stat.php?id=1260462968&web_id=1260462968"></script></div>
    <a href="https://github.com/imlinhanchao/coding-picbed-api" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
</body>

</html>